package com.milhouz.wormdroid.gl.model;

import java.io.IOException;
import java.io.InputStream;

import javax.microedition.khronos.opengles.GL10;
import javax.microedition.khronos.opengles.GL11;
import javax.microedition.khronos.opengles.GL11Ext;

import simpull.Rectangle;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLUtils;
import android.util.Log;

import com.milhouz.wormdroid.gl.util.Grid;

/**
 * This is the OpenGL ES version of a sprite. It is more complicated than the CanvasSprite class because it can be used in more than one way. This class can draw using a grid of verts, a grid of verts
 * stored in VBO objects, or using the DrawTexture extension.
 */
public class GLSprite extends Rectangle {
	public int id;
	public String type;
	// The OpenGL ES texture handle to draw.
	private int mTextureName;
	// The id of the original resource that mTextureName is based on.
	private int mResourceId;
	// If drawing with verts or VBO verts, the grid object defining those verts.
	public Grid mGrid;
	protected static final float Z = 0;
	private static BitmapFactory.Options sBitmapOptions = new BitmapFactory.Options();
	// Color data
	public boolean isPlainColor;
	protected int red, green, blue, alpha;
	public boolean isViewCentered;
	public boolean isHide;
	
	public GLSprite(int id, int x, int y, int width, int height, boolean isFixed, float mass, float elasticity, float friction, int resourceId) {
		super(x, y, width, height, 0f, isFixed, mass, elasticity, friction);
		this.id = id;
		mResourceId = resourceId;
		// Setup the grid.  This is just a quad.
    Grid grid = new Grid(2, 2);
    grid.set(0, 0,  0.0f, 0.0f, 0.0f, 0.0f , 1.0f);
    grid.set(1, 0, getWidth(), 0.0f, 0.0f, 1.0f, 1.0f);
    grid.set(0, 1, 0.0f, getHeight(), 0.0f, 0.0f, 0.0f);
    grid.set(1, 1, getWidth(), getHeight(), 0.0f, 1.0f, 0.0f );
    mGrid = grid;
	}
	
	public void setTextureName(int name) {
		mTextureName = name;
	}

	public int getTextureName() {
		return mTextureName;
	}

	public void setResourceId(int id) {
		mResourceId = id;
	}

	public int getResourceId() {
		return mResourceId;
	}

	public void draw(GL10 gl, int zx, int zy, boolean isZoomed, float zoomFactor) {
		if (!isHide) {
			if (isPlainColor)
				gl.glColor4x(red, green, blue, alpha);
			else
				gl.glBindTexture(GL10.GL_TEXTURE_2D, mTextureName);
			
				// Draw using verts or VBO verts.
				gl.glPushMatrix();
				gl.glLoadIdentity();
				if (isZoomed)
					gl.glScalef(zoomFactor, zoomFactor, 1.0f);
				gl.glTranslatef(getGLX()+zx, getGLY()-zy, Z);
				mGrid.draw(gl, true);
	
				gl.glPopMatrix();
		}
	}
	
	public int loadTextureBitmap(Context context, GL10 gl) {
		int[] texResource = new int [1];
		int[] texGrid = new int[4];
		int textureName = -1;
		mGrid.forgetHardwareBuffers();
		if (context != null && gl != null) {
			gl.glGenTextures(1, texResource, 0);

			textureName = texResource[0];
			gl.glBindTexture(GL10.GL_TEXTURE_2D, textureName);

			gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST);
			gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);

			gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_CLAMP_TO_EDGE);
			gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_CLAMP_TO_EDGE);

			gl.glTexEnvf(GL10.GL_TEXTURE_ENV, GL10.GL_TEXTURE_ENV_MODE, GL10.GL_REPLACE);

			InputStream is = context.getResources().openRawResource(mResourceId);
			Bitmap bitmap;
			try {
				bitmap = BitmapFactory.decodeStream(is, null, sBitmapOptions);
			} finally {
				try {
					is.close();
				} catch (IOException e) {
					// Ignore.
				}
			}

			GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);

			texGrid[0] = 0;
			texGrid[1] = bitmap.getHeight();
			texGrid[2] = bitmap.getWidth();
			texGrid[3] = -bitmap.getHeight();

			bitmap.recycle();

			((GL11) gl).glTexParameteriv(GL10.GL_TEXTURE_2D, GL11Ext.GL_TEXTURE_CROP_RECT_OES, texGrid, 0);

			int error = gl.glGetError();
			if (error != GL10.GL_NO_ERROR) {
				Log.e("wormdroid", "Texture Load GLError: " + error);
			}
			
			if (!mGrid.usingHardwareBuffers()) {
				mGrid.generateHardwareBuffers(gl);
			}
		}
		return textureName;
	}
	
	/* (non-Javadoc)
	 * @see com.android.spritemethodtest.model.IGL#setColor(int, int, int, int)
	 */
	public void setColor(int red,int green,int blue,int alpha) {
		this.red = red;
		this.blue = blue;
		this.green = green;
		this.alpha = alpha;
		isPlainColor = true;
	}
	
	protected float getGLX() {
  	return getX() - (getWidth() / 2);
  }
	
	
	
	protected float getGLY() {
  	return getY() - (getHeight() / 2);
  }

	public Grid getGrid() {
		return mGrid;
	}

	public boolean isPlainColor() {
		return isPlainColor;
	}

}
